﻿#include "../../edit/caret.h"
#include "../../control.h"
#pragma comment(lib, "imm32")

namespace swui
{
	namespace _ctlInterior
	{
		DWORD CALLBACK caret::caretFlusher(LPVOID obj)
		{
			caret* object = (caret*)obj;
			while(WaitForSingleObject(object->hExitEvent, 0) == WAIT_TIMEOUT)
			{
				Sleep(object->flushTime);
				if(object->enabled && object->getLevel() != nullptr
					&& object->getLevel()->getFocus() == object->getLevel()
					|| object->displayStatus == true && object->getLevel() != nullptr)
				{
					object->displayStatus = !object->displayStatus;
					object->getLevel()->redraw();
				} 
			}
			return 0;
		}

		caret::caret() :
			position(0, 0), 
			enabled(false), 
			flushTime(500), 
			displayStatus(false), 
			length(0), 
			level(nullptr), 
			hPen(CreatePen(PS_SOLID, 1, 0)) { }
		void caret::bindExit(HANDLE hExit, HWND hWnd_)
		{
			hExitEvent = hExit;
			hWnd = hWnd_;
			flushThread = CreateThread(0, 0, caret::caretFlusher, this, 0, 0);
		}
		void caret::waitExit()
		{
			WaitForSingleObject(flushThread, INFINITE);
			CloseHandle(flushThread);
			DeleteObject(hPen);
		}
		void caret::enable(bool e) 
		{
			setStatus(e);
			if(enabled != e)
			{
				enabled = e;
				if(enabled)
				{
					HIMC hImc = ImmGetContext(hWnd);
					if(!hImc)
					{
						hImc = ImmCreateContext();
						ImmAssociateContext(hWnd, hImc);
					} else ImmReleaseContext(hWnd, hImc);
				} else {
					HIMC hImc = ImmGetContext(hWnd);
					if(hImc) ImmDestroyContext(hImc);
				}
			}
		}
		void caret::setPos(ctlPoint position)
		{ 
			setStatus(true);
			this->position = position;
			if(getLevel() != nullptr)
			{
				HIMC hImc = ImmGetContext(hWnd);
				CANDIDATEFORM candidate = { 0 };
				candidate.dwStyle = CFS_CANDIDATEPOS;
				ctlRect absRect = getLevel()->getAbsoluteRect();
				position.x += absRect.x;
				position.y += absRect.y;
				POINT pt = { position.x - 30, position.y + getLength() + 3 };
				candidate.ptCurrentPos = pt;
				ImmSetCandidateWindow(hImc, &candidate);
				ImmReleaseContext(hWnd, hImc);
			}
		}
	}
}